package com.tmt.im.service.controller;

import com.alibaba.fastjson2.JSONObject;
import com.tmt.im.common.vo.NewChatSessionVo;
import com.tmt.im.service.config.beans.YunXinProperties;
import com.tmt.im.service.controller.vo.*;
import com.tmt.im.service.helper.PrincipalHelper;
import com.tmt.im.service.interfaces.IChatSessionManager;
import com.tmt.springboot.common.restful.ExecuteResult;
import com.tmt.springboot.common.restful.IExecuteResult;
import com.tmt.springboot.common.restful.ResultWrapper;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.extern.slf4j.Slf4j;
import org.springframework.scheduling.annotation.Async;
import org.springframework.util.StringUtils;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import java.security.Principal;
import java.util.concurrent.CompletableFuture;

/**
 * 即时会话管理接口
 *
 * @Description TODO
 * @Author wuyi
 * @Date 2024/8/6 11:26
 * @Version 1.0
 **/
@Slf4j
@Tag(name = "群组管理相关接口", description = "群组管理相关接口")
@RestController
@RequestMapping("${api-url-prefix}/session")
@Async("asyncTaskExecutor")
public class ChatSessionController {

    private final IChatSessionManager iChatSessionManager;

    private final YunXinProperties yunXinProperties;

    public ChatSessionController(YunXinProperties yunXinProperties,
                                 IChatSessionManager iChatSessionManager) {
        this.yunXinProperties = yunXinProperties;
        this.iChatSessionManager = iChatSessionManager;
    }

    @Operation(summary = "创建聊天群组",
            description = "创建聊天群组",
            operationId = "createSession",
            parameters = {
                    @Parameter(name = "vo", description = "新群组的定义信息", required = true)
            })
    @PostMapping("/create")
    public CompletableFuture<IExecuteResult<ChatSessionDetailVo>> createSession(@RequestBody @Validated NewChatSessionVo vo, Principal principal) {
        if (!StringUtils.hasText(vo.getInviteMsg())) {
            vo.setInviteMsg(yunXinProperties.getGroupInitParam().getInviteMsg());
        }

        //创建聊天会话。
        StringBuilder error = new StringBuilder();
        Long currentUserId = PrincipalHelper.getCurrentUserId(principal);
        ChatSessionDetailVo result = iChatSessionManager.createSession(currentUserId, vo, error);
        return CompletableFuture.completedFuture(result != null ? ExecuteResult.success(result)
                : ExecuteResult.failure(error.toString(), null));
    }

    @Operation(summary = "获取聊天群组信息",
            description = "获取聊天群组信息",
            operationId = "getSessionDetail",
            parameters = {
                    @Parameter(name = "tid", description = "群组ID，如果当前用户是群主或管理员，则返回数据中又群内成员列表信息", required = true)
            })
    @GetMapping("/detail")
    public CompletableFuture<IExecuteResult<ChatSessionDetailVo>> getSessionDetail(@RequestParam("tid") Long tid, Principal principal) {
        StringBuilder error = new StringBuilder();
        Long currentUserId = PrincipalHelper.getCurrentUserId(principal);
        ChatSessionDetailVo result = iChatSessionManager.getSessionDetail(currentUserId, tid, principal, error);
        return CompletableFuture.completedFuture(result != null ? ExecuteResult.success(result)
                : ExecuteResult.failure(error.toString(), null));
    }

    @Operation(summary = "更新聊天群组配置信息",
            description = "更新聊天群组配置信息",
            operationId = "updateSession",
            parameters = {
                    @Parameter(name = "request", description = "更新群配置信息请求对象", required = true)
            })
    @PostMapping("/update")
    public CompletableFuture<IExecuteResult<ChatSessionDetailVo>> updateSession(@RequestBody @Validated UpdateSessionRequest request, Principal principal) {
        Long currentUserId = PrincipalHelper.getCurrentUserId(principal);
        IExecuteResult<ChatSessionDetailVo> result = iChatSessionManager.updateSession(currentUserId, request, principal);
        return CompletableFuture.completedFuture(result);
    }

    @Operation(summary = "解散聊天群组",
            description = "解散聊天群组",
            operationId = "deleteSession",
            parameters = {
                    @Parameter(name = "tid", description = "要删除的群组ID", required = true)
            })
    @PostMapping("/delete")
    public CompletableFuture<IExecuteResult<ResultWrapper<Boolean>>> deleteSession(@RequestParam("tid") Long tid, Principal principal) {
        StringBuilder error = new StringBuilder();
        Long currentUserId = PrincipalHelper.getCurrentUserId(principal);
        boolean result = iChatSessionManager.deleteSession(currentUserId, tid, principal, error);
        return CompletableFuture.completedFuture(result ? ResultWrapper.from(ExecuteResult.success(true))
                : ResultWrapper.from(ExecuteResult.failure(error.toString(), false)));
    }

    @Operation(summary = "解散聊天群组扩展接口",
            description = "解散聊天群组, 使用JSON对象接收传入的参数",
            operationId = "deleteSession",
            parameters = {
                    @Parameter(name = "tid", description = "要删除的群组ID", required = true)
            })
    @PostMapping("/delete/json")
    public CompletableFuture<IExecuteResult<ResultWrapper<Boolean>>> deleteSession(@RequestBody JSONObject param, Principal principal) {
        Long tid = param.getLong("tid");
        if (tid == null){
            IExecuteResult<Boolean> result = ExecuteResult.failure("群组ID(tid)参数不能为空" , false);
            return CompletableFuture.completedFuture(ResultWrapper.from(result));
        }
        return deleteSession(tid, principal);
    }

    @Operation(summary = "群组禁言",
            description = "群组禁言",
            operationId = "bannedSession",
            parameters = {
                    @Parameter(name = "request", description = "群组禁言请求对象", required = true)
            })
    @Deprecated
    @PostMapping("/banned")
    public CompletableFuture<IExecuteResult<ResultWrapper<Boolean>>> bannedSession(@RequestBody @Validated SessionBannedRequest request, Principal principal) {
        StringBuilder error = new StringBuilder();
        Long currentUserId = PrincipalHelper.getCurrentUserId(principal);
        boolean result = iChatSessionManager.bannedSession(currentUserId, request, principal, error);
        return CompletableFuture.completedFuture(result ? ResultWrapper.from(ExecuteResult.success(true))
                : ResultWrapper.from(ExecuteResult.failure(error.toString(), false)));
    }

    @Operation(summary = "修改入群审核策略",
            description = "修改入群审核策略",
            operationId = "changeJoinMode",
            parameters = {
                    @Parameter(name = "request", description = "入群审核策略变更请求对象", required = true)
            })
    @Deprecated
    @PostMapping("/joinMode")
    public CompletableFuture<IExecuteResult<ResultWrapper<Boolean>>> changeJoinMode(@RequestBody @Validated SessionJoinModeRequest request, Principal principal) {
        StringBuilder error = new StringBuilder();
        Long currentUserId = PrincipalHelper.getCurrentUserId(principal);
        boolean result = iChatSessionManager.changeJoinMode(currentUserId, request, principal, error);
        return CompletableFuture.completedFuture(result ? ResultWrapper.from(ExecuteResult.success(true))
                : ResultWrapper.from(ExecuteResult.failure(error.toString(), false)));
    }

    @Operation(summary = "转让群主",
            description = "转让群主",
            operationId = "transferSession",
            parameters = {
                    @Parameter(name = "request", description = "转让群主请求对象", required = true)
            })
    @PostMapping("/transfer")
    public CompletableFuture<IExecuteResult<ResultWrapper<Boolean>>> transferSession(@RequestBody TransferOwnerRequest request, Principal principal) {
        StringBuilder error = new StringBuilder();
        Long currentUserId = PrincipalHelper.getCurrentUserId(principal);
        boolean result = iChatSessionManager.transferSession(currentUserId, request, principal, error);
        return CompletableFuture.completedFuture(result ? ResultWrapper.from(ExecuteResult.success(true))
                : ResultWrapper.from(ExecuteResult.failure(error.toString(), false)));
    }

    @Operation(summary = "添加管理员",
            description = "添加管理员",
            operationId = "addManager",
            parameters = {
                    @Parameter(name = "request", description = "添加管理员请求对象", required = true)
            })
    @PostMapping("/addManager")
    public CompletableFuture<IExecuteResult<ResultWrapper<Boolean>>> addManager(@RequestBody @Validated NewManagerRequest request, Principal principal) {
        StringBuilder error = new StringBuilder();
        Long currentUserId = PrincipalHelper.getCurrentUserId(principal);
        boolean result = iChatSessionManager.addManager(currentUserId, request, principal, error);
        return CompletableFuture.completedFuture(result ? ResultWrapper.from(ExecuteResult.success(true))
                : ResultWrapper.from(ExecuteResult.failure(error.toString(), false)));
    }

    @Operation(summary = "移除管理员",
            description = "移除管理员",
            operationId = "removeManager",
            parameters = {
                    @Parameter(name = "request", description = "移除管理员请求对象", required = true)
            })
    @PostMapping("/removeManager")
    public CompletableFuture<IExecuteResult<ResultWrapper<Boolean>>> removeManager(@RequestBody NewManagerRequest request, Principal principal) {
        StringBuilder error = new StringBuilder();
        Long currentUserId = PrincipalHelper.getCurrentUserId(principal);
        boolean result = iChatSessionManager.removeManager(currentUserId, request, principal, error);
        return CompletableFuture.completedFuture(result ? ResultWrapper.from(ExecuteResult.success(true))
                : ResultWrapper.from(ExecuteResult.failure(error.toString(), false)));
    }

    @Operation(summary = "获取当前用户在某个群组中的详情信息",
            description = "获取当前用户在某个群组中的详情信息",
            operationId = "getMemberDetailInSession",
            parameters = {
                    @Parameter(name = "tid", description = "群组ID", required = true)
            })
    @GetMapping("/memberDetail")
    public CompletableFuture<IExecuteResult<MemberInfo>> getMemberDetailInSession(@RequestParam("tid") Long tid, Principal principal) {
        Long currentUserId = PrincipalHelper.getCurrentUserId(principal);
        IExecuteResult<MemberInfo> result = iChatSessionManager.getMemberDetailInSession(currentUserId, tid);
        return CompletableFuture.completedFuture(result);
    }

    @Operation(summary = "滑动查询群组中的用户列表",
            description = "滑动查询群组中的用户列表",
            operationId = "slideQueryMemberInSession",
            parameters = {
                    @Parameter(name = "request", description = "滑动查询请求对象", required = true)
            })
    @Deprecated
    @PostMapping("/queryMembers")
    public CompletableFuture<IExecuteResult<QueryMembersResponse>> slideQueryMemberInSession(@RequestBody SlideQueryRequest request,
                                                                                             Principal principal) {
        if (request.getMemberType() == null) {
            request.setMemberType(0);
        }
        if (request.getBannedType() == null) {
            request.setBannedType(0);
        }
        Long currentUserId = PrincipalHelper.getCurrentUserId(principal);
        IExecuteResult<QueryMembersResponse> result = iChatSessionManager.slideQueryMemberInSession(currentUserId, request);
        return CompletableFuture.completedFuture(result);
    }

    @Operation(summary = "分页查询群组中的用户列表",
            description = "分页查询群组中的用户列表",
            operationId = "pageQueryMemberInSession",
            parameters = {
                    @Parameter(name = "tid", description = "群组ID", required = true),
                    @Parameter(name = "pageIndex", description = "页序号，从0开始", required = true),
                    @Parameter(name = "pageSize", description = "页尺寸")
            })
    @GetMapping("/queryMembers")
    public CompletableFuture<IExecuteResult<QueryMembersResponse1>> pageQueryMemberInSession(@RequestParam("tid") long tid,
                                                                                             @RequestParam("pageIndex") int pageIndex,
                                                                                             @RequestParam(value = "pageSize", required = false, defaultValue = "20") int pageSize,
                                                                                             Principal principal) {
        Long currentUserId = PrincipalHelper.getCurrentUserId(principal);
        assert currentUserId != null;
        IExecuteResult<QueryMembersResponse1> result = iChatSessionManager.pageQueryMemberInSession(currentUserId, tid, pageIndex, pageSize);
        return CompletableFuture.completedFuture(result);
    }

    @Operation(summary = "群黑名单管理接口",
            description = "将成员拉人或拉出黑名单",
            operationId = "pullInBlackBill",
            parameters = {
                    @Parameter(name = "request", description = "群黑名单管理请求对象")
            })
    @PostMapping("/blackBill")
    public CompletableFuture<IExecuteResult<ResultWrapper<Boolean>>> pullInBlackBill(@RequestBody @Validated SessionBlackBillRequest request, Principal principal) {
        Long currentUserId = PrincipalHelper.getCurrentUserId(principal);
        IExecuteResult<Boolean> result = iChatSessionManager.pullInBlackBill(currentUserId, request);
        return CompletableFuture.completedFuture(ResultWrapper.from(result));
    }

    @Operation(summary = "群黑名单列表接口",
            description = "获取当前群组的黑名单列表",
            operationId = "listBlackBill",
            parameters = {
                    @Parameter(name = "tid", description = "群主ID"),
                    @Parameter(name = "pageIndex", description = "页序号，从0开始"),
                    @Parameter(name = "pageSize", description = "页尺寸")
            })
    @GetMapping("/blackBill/list")
    public CompletableFuture<IExecuteResult<BlackBillResponse>> listBlackBill(@RequestParam("tid") Long tid,
                                                                              @RequestParam("pageIndex") int pageIndex,
                                                                              @RequestParam(value = "pageSize", defaultValue = "20") int pageSize,
                                                                              Principal principal) {
        IExecuteResult<BlackBillResponse> result = iChatSessionManager.listBlackBill(tid, pageIndex, pageSize);
        return CompletableFuture.completedFuture(result);
    }

}
